package com.group01.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.group01.dto.User.*;
import com.group01.enums.CodeAndMessageEnum;
import com.group01.exception.SystemException;
import com.group01.pojo.User;
import com.group01.result.PageTemplate;
import com.group01.result.Result;
import com.group01.service.UserService;
import com.group01.mapper.UserMapper;
import com.group01.utils.AESUtil;
import com.group01.utils.BeanCopyUtils;
import com.group01.utils.CommonUtils;
import com.group01.utils.JwtUtil;
import com.group01.vo.Admin.AdminLoginVO;
import com.group01.vo.User.UserGetInfoByIdVO;
import com.group01.vo.User.UserGetPageVO;
import lombok.SneakyThrows;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author 19559
* @description 针对表【es_user(用户表)】的数据库操作Service实现
* @createDate 2024-06-20 08:47:55
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{

    private final UserMapper userMapper;

    /**
     * 注入UserMapper
     */
    public UserServiceImpl(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    /**
     * 分页+条件查询用户信息
     * @param pageNum   当前页码
     * @param pageSize  每页大小
     * @param username  用户名
     * @param status    用户状态
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return {@link Result }<{@link List }<{@link User }>>
     */
    @Override
    public PageTemplate<UserGetPageVO> getPage(Integer pageNum, Integer pageSize, String username, String status, String startTime, String endTime) {

        if(Objects.isNull(pageNum)) {
            throw new SystemException(CodeAndMessageEnum.PAGE_NUM_IS_NOT_NULL);
        }

        // 创建查询条件构造器
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .like(StringUtils.hasText(username) , User::getUsername, username)
                .eq(StringUtils.hasText(status), User::getStatus, status)
                .ge(StringUtils.hasText(startTime), User::getRegisterTime, startTime)
                .le(StringUtils.hasText(endTime), User::getRegisterTime, endTime);
        // 创建分页对象
        Page<User> userPage = new Page<>(pageNum, pageSize);
        // 核心查询
        userMapper.selectPage(userPage, queryWrapper);

        // Bean拷贝
        List<UserGetPageVO> vos = BeanCopyUtils.copyBeanList(userPage.getRecords(), UserGetPageVO.class);

        // 返回分页结果
        return new PageTemplate<>(userPage.getTotal(), vos);
    }

    /**
     * 获取用户信息
     * @return {@link Result }<{@link UserGetInfoByIdVO }>
     */
    @Override
    public Result<UserGetInfoByIdVO> getUserInfo() {
        // 获取当前用户id
        Integer id = CommonUtils.getLocalId();
        User user = userMapper.selectById(id);
        // Bean拷贝
        return Result.success("获取用户信息成功", BeanCopyUtils.copyBean(user, UserGetInfoByIdVO.class));
    }

    /**
     * 注册用户
     * @param registerDTO 注册用户传输层DTO对象类
     * @return {@link Result }<{@link String }>
     */
    @SneakyThrows
    @Override
    public Result<String> register(RegisterDTO registerDTO) {
        // 参数校验
        if(userMapper.checkUsername(registerDTO.getUsername()) > 0 ) {
            return Result.error("用户名已经被占用!");
        }
        // 密码 -> 密文
        String entryPass = AESUtil.encrypt(registerDTO.getPassword());
        registerDTO.setPassword(entryPass);
        registerDTO.setRegisterTime(new Date());
        // Bean拷贝
        User user = BeanCopyUtils.copyBean(registerDTO, User.class);
        user.setRoleId(2);
        // 执行新增
        if(userMapper.insert(user) == 1) {
            return Result.success("注册新用户成功!", null);
        }
        return Result.error("注册用户失败");
    }

    /**
     * 修改密码
     * @param userUpdatePassDTO 修改密码传输层DTO对象类
     * @return {@link Result }<{@link String }>
     */
    @SneakyThrows
    @Override
    public Result<String> updatePassword(UserUpdatePassDTO userUpdatePassDTO) {
        // 对旧密码进行加密
        String entryOldPass = AESUtil.encrypt(userUpdatePassDTO.getOldPassword());
        // 获取当前用户id
        Integer id = CommonUtils.getLocalId();
        // 校验旧密码是否正确
        if (userMapper.checkPassword(id, entryOldPass) == 0) {
            return Result.error("旧密码不正确!");
        }
        // 加密新密码
        String entryNewPass = AESUtil.encrypt(userUpdatePassDTO.getNewPassword());
        // 执行修改
        if (userMapper.updatePassword(id, entryNewPass)) {
            return Result.success("修改密码成功!", null);
        }
        return Result.error("修改密码失败!");
    }


    /**
     * 新增用户
     * @param userInsertInfoDTO 添加用户传输层DTO对象类
     * @return {@link Result }<{@link String }>
     */
    @SneakyThrows
    @Override
    public Result<String> addUser(UserInsertInfoDTO userInsertInfoDTO) {
        // 参数校验
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, userInsertInfoDTO.getUsername());
        Long count = userMapper.selectCount(queryWrapper);
        if(count > 0) {
            return Result.error("用户名已经被占用!");
        }
        // 密码 -> 密文
        String entryPass = AESUtil.encrypt(userInsertInfoDTO.getPassword());
        userInsertInfoDTO.setPassword(entryPass);
        userInsertInfoDTO.setRegisterTime(new Date());
        // Bean拷贝
        User user = BeanCopyUtils.copyBean(userInsertInfoDTO, User.class);
        // 执行新增
        if(userMapper.insert(user) == 1) {
            return Result.success("添加新用户成功!" , null);
        }
        return Result.error("添加用户失败");
    }

    /**
     * 根据用户ID获取用户信息
     * @param id 用户id
     * @return {@link UserGetInfoByIdVO }
     */
    @Override
    public UserGetInfoByIdVO getUserById(Integer id) {

        if(Objects.isNull(id)) {
            throw new SystemException(CodeAndMessageEnum.USER_ID_IS_NOT_NULL);
        }

        // 查询用户信息
        User user = userMapper.selectById(id);

        // 用户信息是否为空
        if(Objects.isNull(user)) {
            throw new SystemException(CodeAndMessageEnum.USER_NOT_EXIST);
        }

        // Bean拷贝并返回
        return BeanCopyUtils.copyBean(user, UserGetInfoByIdVO.class);
    }

    /**
     * 修改用户信息
     * @param updateInfoDTO 传输对象dto
     * @return boolean
     */
    @Override
    public Result<UserGetInfoByIdVO> updateUserInfo(UserUpdateInfoDTO updateInfoDTO) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        // 校验真实性
        User user = userMapper.selectById(updateInfoDTO.getId());
        if(Objects.isNull(user)) {
            return Result.error("该用户不存在!", null);
        }

        // 排除自己
        queryWrapper
                .ne(User::getId, updateInfoDTO.getId())
                .eq(User::getUsername, updateInfoDTO.getUsername());
        // 如果排除自己后，修改的用户名与其他用户一致的个数>0即存在,那么false
        Long count = userMapper.selectCount(queryWrapper);
        if(count > 0) {
            return Result.error("该用户名已经被占用!", null);
        }

        // Bean拷贝
        user = BeanCopyUtils.copyBean(updateInfoDTO, User.class);

        // 执行修改
        userMapper.updateById(user);

        return Result.success(CodeAndMessageEnum.SUCCESS_NODATA, BeanCopyUtils.copyBean(user, UserGetInfoByIdVO.class));
    }

    /**
     * 修改用户账号状态
     * @param userUpdateStatusDTO 修改用户状态传输对象DTO
     * @return {@link Result }<{@link String }>
     */
    @Override
    public Result<String> updateUserStatus(UserUpdateStatusDTO userUpdateStatusDTO) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId , userUpdateStatusDTO.getId());

        // 检查用户id是否正确
        Long count = userMapper.selectCount(queryWrapper);
        if(count != 1) {
            return Result.error("该用户不存在!");
        }
        LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(User::getId, userUpdateStatusDTO.getId())
                .set(User::getStatus, userUpdateStatusDTO.getStatus());

        // 修改用户状态
        userMapper.update(updateWrapper);
        return Result.success(CodeAndMessageEnum.SUCCESS_NODATA);
    }

    /**
     * 删除与批量删除用户信息
     * @param ids 批量的用户id值
     * @return {@link Result }<{@link String }>
     */
    @Transactional
    @Override
    public Result<String> deleteUsersByIds(String ids) {
        List<Integer> idList = Arrays.stream(ids.split(","))
                .map(Integer::parseInt)
                .collect(Collectors.toList());
        userMapper.deleteBatchIds(idList);
        return Result.success(CodeAndMessageEnum.DELETE_MANY_SUCCESS);
    }

}




